package org.esk.dablog.web.util;

import org.apache.commons.lang.math.RandomUtils;
import org.apache.commons.collections.ListUtils;

import java.util.List;
import java.util.AbstractList;
import java.util.AbstractMap;
import java.util.Set;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;

/**
 * This class is used to provide random access to list elements
 * User: jc
 * Date: 30.11.2006
 * Time: 19:22:16
 * $Id:$
 */
public class ListRandomAccess extends AbstractMap {

    /**
     * fake get() method always returns ListAccess instance;
     *
     * @param key
     * @return
     */
    public Object get(Object key) {
        return new ListAccess(new ArrayList((Collection) key));
    }

    /**
     * fake entrySet method;
     *
     * @return
     */
    public Set entrySet() {
        return Collections.EMPTY_SET;
    }

    /**
     * inner class providing random list access
     */
    public static class ListAccess {
        private List list;
        private Set alreadyProcessed = new HashSet();

        public ListAccess(List list) {
            this.list = list;
        }

        /**
         * returns random list's value
         *
         * @return
         */
        public Object getRandom() {
            if (list == null || list.isEmpty()) {
                return null;
            }
            int random = 0;
            do {

                random = RandomUtils.nextInt(list.size());
            }
            while (alreadyProcessed.contains(random) && alreadyProcessed.size() < list.size());

            if (alreadyProcessed.size() >= list.size()) {
                alreadyProcessed.clear();
            }
            alreadyProcessed.add(random);
            return list.get(random);
        }

        /**
         * checks if list is empty
         * @return
         */
        public boolean isEmpty() {
            return list == null || list.isEmpty();
        }

        /**
         * 
         * @return
         */
        public int getSize() {
            if(list == null) {
                return 0;
            }
            return list.size();
        }
    }
}
